package com.mybatis.service.impl;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidPooledConnection;
import com.mybatis.constant.Constants;
import com.mybatis.constant.DataSourceConstants;
import com.mybatis.dto.request.DatabaseParam;
import com.mybatis.exception.CommonException;
import com.mybatis.strategy.DatabaseStrategy;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.sql.*;
import java.util.ArrayList;
import java.util.List;

/**
 * @desc: oracle数据库
 * @projectName: mybatis-generator-parent
 * @author: xhs
 * @date: 2023-7-22 022 16:27
 * @version: JDK 1.8
 */
@Slf4j
@Service("oracle")
public class OracleDatabaseStrategyImpl implements DatabaseStrategy {

    /**
     * 测试连接数据库
     *
     * @param databaseParam 连接数据库入参
     * @return Connection
     */
    @Override
    public Connection databaseConnection(DatabaseParam databaseParam) {
        try {
            log.info("{}测试连接{}数据库{}", Constants.START, databaseParam.getDataBaseType(), Constants.END);
            Class.forName(DataSourceConstants.ORACLE_DRIVER);
            // 数据库地址
            String url = DataSourceConstants.ORACLE_URL + databaseParam.getDataBaseUrl() + Constants.COLON + databaseParam.getDataBasePort() + Constants.SLASH + databaseParam.getDataBaseName();
            log.info("{}数据库地址:{}{}", Constants.START, url, Constants.END);
            //获取连接对象
            return DriverManager.getConnection(url, databaseParam.getDataBaseUserName(), databaseParam.getDataBasePassword());
        } catch (ClassNotFoundException | SQLException e) {
            log.info("{}测试连接{}数据库异常{}", Constants.START, databaseParam.getDataBaseType(), Constants.END);
            throw new CommonException(databaseParam.getDataBaseType() + Constants.IN + e.getMessage());
        }
    }

    /**
     * 设置数据库连接信息
     *
     * @param databaseParam 数据库连接信息
     * @return DruidDataSource
     */
    @Override
    public DruidDataSource setDataSource(DatabaseParam databaseParam) {
        // 配置数据源
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName(DataSourceConstants.ORACLE_DRIVER);
        // 数据库地址
        String url = DataSourceConstants.ORACLE_URL + databaseParam.getDataBaseUrl() + Constants.COLON + databaseParam.getDataBasePort() + Constants.SLASH + databaseParam.getDataBaseName();
        log.info("{}数据库地址:{}{}", Constants.START, url, Constants.END);
        dataSource.setUrl(url);
        dataSource.setUsername(databaseParam.getDataBaseUserName());
        dataSource.setPassword(databaseParam.getDataBasePassword());
        return dataSource;
    }

    /**
     * 获取数据库中所有表名称
     *
     * @param databaseParam 数据库连接信息
     * @return List<String>
     */
    @Override
    public List<String> getTableList(DatabaseParam databaseParam) {
        DruidDataSource druidDataSource = this.setDataSource(databaseParam);
        List<String> tables = null;
        DruidPooledConnection connection = null;
        try {
            connection = druidDataSource.getConnection();
            Statement stmt = connection.createStatement();
            ResultSet showTables = stmt.executeQuery(DataSourceConstants.ORACLE_TABLES);
            tables = new ArrayList<>();
            while (showTables.next()) {
                tables.add(showTables.getString(DataSourceConstants.ORACLE_TABLE_NAME));
            }
        } catch (SQLException e) {
            throw new CommonException("获取数据库中所有表名称异常", e);
        } finally {
            try{
                assert connection != null;
                if (!connection.isClosed()) {
                    // 关闭数据库连接
                    connection.close();
                }
            }catch (SQLException e){
                throw new CommonException("获取数据库中所有表名称异常", e);
            }
        }
        return tables;
    }
}
